#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <string.h>
// #include <cjson/cJSON.h>
#include "./cJSON.h"
#include <curl/curl.h>
#include <ctype.h>
#include "./ui/ui.h"

static const char *getenv_default(const char *name, const char *dflt)
{
    return getenv(name) ?: dflt;
}

#if LV_USE_LINUX_FBDEV
static void lv_linux_disp_init(void)
{
    const char *device = getenv_default("LV_LINUX_FBDEV_DEVICE", "/dev/fb0");
    lv_display_t *disp = lv_linux_fbdev_create();

    lv_linux_fbdev_set_file(disp, device);
}
#elif LV_USE_SDL
static void lv_linux_disp_init(void)
{
    const int width = atoi(getenv("LV_SDL_VIDEO_WIDTH") ?: "800");
    const int height = atoi(getenv("LV_SDL_VIDEO_HEIGHT") ?: "480");

    lv_sdl_window_create(width, height);
}
#else
// #error Unsupported configuration
#endif

void my_chinese_font(char *text)
{
    // 1.创建中文字体
    lv_font_t *font = lv_freetype_font_create("/home/gec/simkai.ttf", // 👍加载字库文件
                                              LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
                                              24,
                                              LV_FREETYPE_FONT_STYLE_NORMAL);

    // 2.创建中文字体样式
    static lv_style_t style;
    lv_style_init(&style);                                 // 初始化样式
    lv_style_set_text_font(&style, font);                  // 设置中文字体样式
    lv_style_set_text_align(&style, LV_TEXT_ALIGN_CENTER); // 字体居中显示

    lv_obj_t *label = lv_label_create(lv_screen_active());
    lv_obj_add_style(label, &style, 0); // 👍给标签添加中文字体
    lv_label_set_text(label, text);
    lv_obj_center(label);
}


extern lv_pinyin_dict_t my_dict[];
char api_response[4096] = {0};
lv_obj_t *answer_label = NULL;
//定义一个锁
pthread_mutex_t api_mutex = PTHREAD_MUTEX_INITIALIZER;//初始化锁
struct MemoryStruct {
    char* memory;
    size_t size;
    char current_event[128];
};

static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    size_t realsize = size * nmemb;
    struct MemoryStruct* mem = (struct MemoryStruct*)userp;

    char* ptr = realloc(mem->memory, mem->size + realsize + 1);
    if (!ptr) {
        fprintf(stderr, "内存不足 (realloc failed)\n");
        return 0;
    }
    mem->memory = ptr;
    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = '\0';

    char* line_start = mem->memory;
    char* line_end;
    while ((line_end = strstr(line_start, "\n")) != NULL) {
        *line_end = '\0';

        char* event_prefix = strstr(line_start, "event:");
        if (event_prefix != NULL) {
            event_prefix += strlen("event:");
            while (*event_prefix == ' ' || *event_prefix == '\t') event_prefix++;
            memset(mem->current_event, 0, sizeof(mem->current_event));
            strncpy(mem->current_event, event_prefix, sizeof(mem->current_event) - 1);
        }

        char* data_prefix = strstr(line_start, "data:");
        if (data_prefix != NULL && strstr(mem->current_event, "conversation.message.delta") != NULL) {
            char* json_data = data_prefix + strlen("data:");
            while (*json_data == ' ' || *json_data == '\t') json_data++;

            cJSON* json = cJSON_Parse(json_data);
            if (json != NULL) {
                cJSON* role = cJSON_GetObjectItemCaseSensitive(json, "role");
                cJSON* type = cJSON_GetObjectItemCaseSensitive(json, "type");
                cJSON* content = cJSON_GetObjectItemCaseSensitive(json, "content");

                if (role && cJSON_IsString(role) && strcasecmp(role->valuestring, "assistant") == 0 &&
                    type && cJSON_IsString(type) && strcasecmp(type->valuestring, "answer") == 0 &&
                    content && cJSON_IsString(content) && content->valuestring != NULL) {

                    strncat(api_response, content->valuestring, sizeof(api_response) - strlen(api_response) - 1);
                    //加锁
                    pthread_mutex_lock(&api_mutex);
                    lv_label_set_text(answer_label, api_response);
                    lv_obj_scroll_to_view(answer_label, LV_ANIM_ON);
                    //解锁
                    pthread_mutex_unlock(&api_mutex);
                }
                cJSON_Delete(json);
            }
        }

        line_start = line_end + 1;
    }

    if (line_start > mem->memory) {
        size_t remaining = mem->size - (line_start - mem->memory);
        memmove(mem->memory, line_start, remaining);
        mem->size = remaining;
        mem->memory[mem->size] = '\0';
    }

    return realsize;
}

int send_to_coze(const char* message) {
    CURL *curl;
    CURLcode res;
    int ret_val = 0;

    cJSON *data = cJSON_CreateObject();
    cJSON_AddStringToObject(data, "bot_id", "7552821894551126066");
    cJSON_AddStringToObject(data, "user_id", "yesi");
    cJSON_AddTrueToObject(data, "stream");
    cJSON_AddTrueToObject(data, "auto_save_history");

    cJSON *additional_messages = cJSON_CreateArray();
    cJSON *usermessage = cJSON_CreateObject();
    cJSON_AddStringToObject(usermessage, "role", "user");
    cJSON_AddStringToObject(usermessage, "content", message);
    cJSON_AddStringToObject(usermessage, "content_type", "text");
    cJSON_AddItemToArray(additional_messages, usermessage);
    cJSON_AddItemToObject(data, "additional_messages", additional_messages);

    char *json_data = cJSON_PrintUnformatted(data);
    if (!json_data) {
        fprintf(stderr, "无法生成 JSON 请求数据\n");
        cJSON_Delete(data);
        return -1;
    }

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if (curl) {
        struct MemoryStruct chunk;
        chunk.memory = malloc(1);
        chunk.size = 0;
        memset(chunk.current_event, 0, sizeof(chunk.current_event));
        memset(api_response, 0, sizeof(api_response));

        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: application/json");
        headers = curl_slist_append(headers, "Accept: application/json");
        headers = curl_slist_append(headers, "Authorization: Bearer pat_Z8YIxeryfEt46iXYK3PjvuvmGdbxXq8jYqOH4mK3PS7GKOhLqSBkZwjrNzfJ51yJ");

        curl_easy_setopt(curl, CURLOPT_URL, "https://api.coze.cn/v3/chat");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

        res = curl_easy_perform(curl);
        if (res != CURLE_OK) 
        {
            fprintf(stderr, "curl 请求失败: %s\n", curl_easy_strerror(res));
            ret_val = -1;
        } 
        free(json_data);
        free(chunk.memory);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);
    } else {
        free(json_data);
        fprintf(stderr, "curl 初始化失败\n");
        ret_val = -1;
    }

    curl_global_cleanup();
    return ret_val;
}

// 子线程函数（执行curl请求，不阻塞主线程）
void *send_coze_thread(void *arg) 
{
    const char *message = (const char *)arg;
    int ret = send_to_coze(message);
    // 使用 LV_EVENT_REFRESH 替代自定义事件
    if (ret != 0) {
        lv_event_send(answer_label, LV_EVENT_REFRESH, (void *)"请求失败，请检查网络或重试！");
    }
    free(arg); // 释放文本副本内存
    return NULL;
}

// 主线程事件回调（处理子线程的请求失败通知）
static void label_event_cb(lv_event_t *e) 
{
    lv_event_code_t code = lv_event_get_code(e);
    // 响应 LV_EVENT_REFRESH 事件
    if (code == LV_EVENT_REFRESH) 
    {
        const char *error_msg = (const char *)lv_event_get_param(e);
        if (error_msg != NULL) 
        {
            lv_label_set_text(answer_label, error_msg);
        }
    }
}

// 确认键回调（用子线程执行curl请求）
void kb_confirm_event_cb(lv_event_t *e)
{
    printf("确认键（√）被点击，触发 LV_EVENT_READY 事件\n");

    lv_obj_t *kb = lv_event_get_target(e);
    lv_obj_t *ta1 = lv_keyboard_get_textarea(kb);

    if (ta1 == NULL) 
    {
        fprintf(stderr, "文本框对象为空，无法获取输入内容\n");
        return;
    }

    const char *input = lv_textarea_get_text(ta1);
    if (input == NULL || strlen(input) == 0) 
    {
        lv_label_set_text(answer_label, "请先输入问题再提交！");
        return;
    }

    memset(api_response, 0, sizeof(api_response));
    lv_label_set_text(answer_label, "正在请求，请稍候...");

    // 创建子线程执行curl请求，不阻塞主线程
    pthread_t tid;
    char *msg_copy = strdup(input); // 复制输入文本（避免文本框清空后指针失效）
    pthread_create(&tid, NULL, send_coze_thread, msg_copy);
    pthread_detach(tid); // 分离线程，避免内存泄漏

    lv_textarea_set_text(ta1, "");
    lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
}

void ta_event_cb(lv_event_t *e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *kb = lv_event_get_user_data(e);
    if (code == LV_EVENT_FOCUSED)
    {
        lv_obj_remove_flag(kb, LV_OBJ_FLAG_HIDDEN);   
    }
    else if( code == LV_EVENT_DEFOCUSED)
    {
        lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
    }
}

void init_my_keyboard() {
    lv_font_t *font = lv_freetype_font_create("/home/gec/simkai.ttf",
                                              LV_FREETYPE_FONT_RENDER_MODE_BITMAP,
                                              24,
                                              LV_FREETYPE_FONT_STYLE_NORMAL);
    if (!font) 
    {
        fprintf(stderr, "中文字体加载失败！请检查 /home/gec/simkai.ttf 路径\n");
        return;
    }

    static lv_style_t style;
    lv_style_init(&style);
    lv_style_set_text_font(&style, font);
    lv_style_set_text_align(&style, LV_TEXT_ALIGN_LEFT);
    lv_style_set_text_color(&style, lv_color_hex(0x000000));

    lv_obj_t *ta1 = lv_textarea_create(lv_screen_active());
    lv_obj_set_size(ta1, 700, 100);
    lv_obj_add_style(ta1, &style, 0);
    lv_obj_align(ta1, LV_ALIGN_CENTER, 0, -190);

    lv_obj_t *answer_scroll = lv_obj_create(lv_screen_active());
    lv_obj_remove_style_all(answer_scroll);
    lv_obj_set_size(answer_scroll, 700, 380);
    lv_obj_align(answer_scroll, LV_ALIGN_CENTER, 0, 50);
    lv_obj_set_flex_align(answer_scroll, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
    lv_obj_set_scroll_dir(answer_scroll, LV_DIR_VER);

    answer_label = lv_label_create(answer_scroll);
    lv_obj_set_width(answer_label, 700);
    lv_obj_set_height(answer_label, LV_SIZE_CONTENT);
    lv_label_set_text(answer_label, "等待回答...");
    lv_obj_add_style(answer_label, &style, 0);

    // 绑定 LV_EVENT_REFRESH 事件处理请求失败
    lv_obj_add_event_cb(answer_label, label_event_cb, LV_EVENT_REFRESH, NULL);

    lv_obj_t *kb = lv_keyboard_create(lv_screen_active());
    lv_keyboard_set_textarea(kb, ta1);
    lv_obj_set_size(kb, 700, 250);
    lv_obj_align(kb, LV_ALIGN_BOTTOM_MID, 0, 0);

    lv_obj_t *pinyin_ime = lv_ime_pinyin_create(lv_screen_active());
    lv_obj_add_style(pinyin_ime, &style, 0);
    lv_ime_pinyin_set_dict(pinyin_ime, my_dict);
    lv_ime_pinyin_set_keyboard(pinyin_ime, kb);
    
    lv_obj_add_event_cb(ta1, ta_event_cb, LV_EVENT_ALL ,kb);
    lv_obj_add_event_cb(kb, kb_confirm_event_cb, LV_EVENT_READY, NULL);

    lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
}

int main(void)
{
    
    lv_init();
    /*Linux display device init*/
    lv_linux_disp_init();

#if LV_USE_SDL
    // init input device
    lv_sdl_mouse_create();
    lv_sdl_keyboard_create();
    lv_sdl_mousewheel_create();
#endif

#if LV_USE_LINUX_FBDEV
    // 创建输入设备
    lv_indev_t *touch = lv_evdev_create(LV_INDEV_TYPE_POINTER, "/dev/input/event0");
    // 校准输入设备屏幕坐标
    // lv_evdev_set_calibration(touch, 0, 0, 1024, 600); // 黑色边框的屏幕
    lv_evdev_set_calibration(touch, 0, 0, 800, 480);  // 蓝色边框的屏幕
#endif
    //初始化锁
    pthread_mutex_init(&api_mutex, NULL);
    init_my_keyboard();
    /*Handle LVGL tasks*/
    while (1)
    {
        //加锁
        pthread_mutex_lock(&api_mutex);
        lv_timer_handler();
        usleep(5000);
        //解锁
        pthread_mutex_unlock(&api_mutex);
    }
    return 0;
}
